home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / dos / communic / pcmail / main / xpres.c < prev   
Encoding:
C/C++ Source or Header  |  1994-06-05  |  7.1 KB  |  342 lines

  1. /*++
  2. /* NAME
  3. /*      xpres 3
  4. /* SUMMARY
  5. /*      communications port i/o
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      cico
  10. /* SYNOPSIS
  11. /*      xopen()
  12. /*
  13. /*      xclose()
  14. /*
  15. /*      xread(dummy,buf,len)
  16. /*      int dummy,len;
  17. /*      char *buf;
  18. /*
  19. /*      xwrite(dummy,buf,len)
  20. /*      int dummy,len;
  21. /*      char *buf;
  22. /*
  23. /*      xioctl(flag)
  24. /*      int flag;
  25. /* DESCRIPTION
  26. /*      The functions in this module perform functions analogous
  27. /*      to unix system calls, for the serial port of IBM-PC workalikes.
  28. /*
  29. /*      xopen() initializes a serial port. Also needed under UNIX.
  30. /*
  31. /*      xclose() closes a port.
  32. /*
  33. /*      xread(), xwrite() do not use their first argument. Under UNIX
  34. /*    one should use the standard read() and write() system calls.
  35. /*
  36. /*      xioctl() enables xon/xoff flow control if its argument
  37. /*      is nonzero. Not used under UNIX.
  38. /* SEE ALSO
  39. /*      comport.asm, IBM-PC comm routines by Tim Pozar
  40. /* DIAGNOSTICS
  41. /*      The read functions returns EOF in case of timeout; the write
  42. /*      function never detects any failure.
  43. /* BUGS
  44. /*      The xioctl() function is utterly primitive.
  45. /* AUTHOR(S)
  46. /*      MS-DOS parts derived from uuslave software (John Gilmore)
  47. /*    published on usenet early 1987. Bugs fixed & severely hacked by
  48. /*
  49. /*      W.Z. Venema
  50. /*      Eindhoven University of Technology
  51. /*      Department of Mathematics and Computer Science
  52. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  53. /* CREATION DATE
  54. /*      Sat Mar 28 23:01:43 GMT+1:00 1987
  55. /* LAST MODIFICATION
  56. /*    90/01/22 13:02:59
  57. /* VERSION/RELEASE
  58. /*    2.1
  59. /*--*/
  60.  
  61. #include <stdio.h>
  62.  
  63. #include "defs.h"
  64. #include "params.h"
  65. #include "comm.h"            /* baud rates, tty ports,... */
  66. #include "status.h"
  67. #include "sysdep.h"            /* other system dependencies */
  68. #include "logs.h"
  69.  
  70. #ifdef    unix
  71. #   include <sgtty.h>
  72. #   include <signal.h>
  73. #   include <setjmp.h>
  74. #endif
  75.  
  76. #ifdef    MSDOS
  77. #   define B(x)    (115200/(x))
  78. static int sigint();
  79. static void get_time();
  80.  
  81. #endif
  82.  
  83. typedef struct {            /* baud-rate lookup table */
  84.     char   *name;
  85.     int     code;
  86. } Baud_table;
  87.  
  88. Baud_table btable[] = {
  89. #ifdef    unix
  90.     "50",    B50,
  91.     "75",    B75,
  92.     "110",    B110,
  93.     "134",    B134,
  94.     "150",    B150,
  95.     "300",    B300,
  96.     "600",    B600,
  97.     "1200",    B1200,
  98.     "1800",    B1800,
  99.     "2400",    B2400,
  100.     "4800",    B4800,
  101.     "9600",    B9600,
  102. #endif
  103. #ifdef    MSDOS
  104.     "50",    B(50),
  105.     "75",    B(75),
  106.     "110",    B(110),
  107.     "134",    B(134),
  108.     "150",    B(150),
  109.     "300",    B(300),
  110.     "600",    B(600),
  111.     "1200",    B(1200),
  112.     "1800",    B(1800),
  113.     "2400",    B(2400),
  114.     "4800",    B(4800),
  115.     "9600",    B(9600),
  116. #endif
  117.     0,        0,
  118. };
  119.  
  120. /* xopen - open communications port; parameters taken from setup table */
  121.  
  122. xopen()
  123. {
  124.     register Baud_table *bp;
  125.  
  126. #ifdef    unix
  127.     struct sgttyb ttmode;
  128.  
  129. #endif
  130.  
  131.     for (bp = btable; bp->name; bp++)        /* look up baud rate */
  132.     if (strcmp(bp->name, COMM_RATE) == 0)
  133.         break;
  134.     if (bp->name == 0) {            /* bad baud rate in setup */
  135.     debug(4) ("Invalid baud rate %s\n", COMM_RATE);
  136.     exit(E_BADSETUP);
  137.     }
  138. #ifdef    unix
  139.     if ((ttfd = open(COMM_LINE, 2)) < 0) {    /* try to access port */
  140.     debug(4) ("Cannot access %s\n", COMM_LINE);
  141.     exit(E_BADSETUP);
  142.     }
  143. #ifndef SIII
  144.     if (ioctl(ttfd, TIOCEXCL))            /* exclusive access */
  145.     exit(E_BADSETUP);            /* not a terminal */
  146. #endif
  147.     ioctl(ttfd, TIOCHPCL);            /* hangup when done */
  148.     gtty(ttfd, &ttmode);            /* get port status */
  149.     ttmode.sg_ispeed = ttmode.sg_ospeed = bp->code;    /* set baud rate */
  150.     ttmode.sg_flags |= (RAW);            /* raw mode */
  151. #ifdef    SIII
  152.     ttmode.sg_flags &= ~ECHO;
  153. #else
  154.     ttmode.sg_flags &= ~(ECHO | TANDEM | CBREAK);    /* no echo, crlf, flow
  155.                              * control */
  156. #endif
  157.     stty(ttfd, &ttmode);
  158. #endif
  159.  
  160. #ifdef MSDOS
  161.     set_tty(bp->code);                /* set baud rate, DTR */
  162.     init_comm();                /* turn interrupts on */
  163.     signal(SIGINT, sigint);            /* must reset tty */
  164.     inp_flush();                /* flush garbage */
  165.     sleep(3);
  166. #endif
  167. }
  168.  
  169. /* xclose - release the communications port */
  170.  
  171. xclose()
  172. {
  173. #ifdef    unix
  174.     close(ttfd);
  175. #endif
  176.  
  177. #ifdef MSDOS
  178.     uninit_comm();
  179. #endif
  180. }
  181.  
  182. /* xread - read from the serial port */
  183.  
  184. #ifdef    MSDOS
  185.  
  186. xread(fd, buf, cnt)
  187. int     fd;
  188. char   *buf;
  189. register int cnt;
  190. {
  191.     register char *p = buf;
  192.     register int c;
  193.  
  194.     while (cnt > 0 && (c = xgetc()) != EOF) {
  195.     *p++ = c;
  196.     cnt--;
  197.     }
  198.     return (p - buf ? p - buf : -1);
  199. }
  200.  
  201. #endif                    /* MSDOS xwrite() */
  202.  
  203. /* xgetc - read one character from serial port */
  204.  
  205. #ifdef    unix
  206. jmp_buf xbuf;
  207.  
  208. static  timeout()
  209. {                    /* aux function for xgetc */
  210.     longjmp(xbuf, 1);
  211. }
  212.  
  213. xgetc()
  214. {                    /* return next char */
  215.     char    ch;
  216.  
  217.     if (setjmp(xbuf))                /* in case we time out */
  218.     return (EOF);                /* we just did */
  219.     signal(SIGALRM, timeout);            /* set timer response */
  220.     alarm(BYTE_TIMEOUT);            /* set timer */
  221.  
  222.     if (read(ttfd, &ch, 1) != 1)        /* go wait for character */
  223.     return(EOF);
  224.     alarm(0);                    /* turn timer off */
  225.     return (ch & 0377);                /* successfull termination */
  226. }
  227.  
  228. #endif                    /* unix xgetc() */
  229.  
  230. #ifdef MSDOS
  231.  
  232. xgetc()
  233. {
  234.     char    data;
  235.  
  236.     int     i;
  237.     unsigned s;
  238.     TIME    n;
  239.  
  240.     i = 0;
  241.     get_time(&n);
  242.     s = n.sec;
  243.  
  244.     /*
  245.      * Implement timeouts by staring at the clock while we wait. When the
  246.      * second hand moves, bump our counter.  This is a lot easier than
  247.      * figuring out the time when we'd time out (in hours, minutes, and
  248.      * seconds!) and comparing against that, which is what people tend to do
  249.      * in Unix where the time is just an integer number of seconds.
  250.      */
  251.     while (i < BYTE_TIMEOUT) {
  252.     while (s == n.sec) {
  253.         if (inp_cnt() != 0) {
  254.         data = inp_char();
  255.         return (data & 0xFF);
  256.         }
  257.         get_time(&n);
  258.     }
  259.     s = n.sec;
  260.     ++i;
  261.     }
  262.     return (EOF);
  263. }
  264.  
  265. /* xwrite - write buffer to serial port */
  266.  
  267. xwrite(fd, buf, ctr)
  268. int     fd;
  269. register char *buf;
  270. int     ctr;
  271. {
  272.     register int i = ctr;
  273.  
  274.     while (i-- > 0)
  275.     outp_char(*buf++);
  276.     return ctr;
  277. }
  278.  
  279. /*
  280.  * Routines specific to MS-DOS
  281.  *
  282.  * xioctl()    enable xon/xoff
  283.  * get_timer()    read current time
  284.  * sigint()    clean up interrupt handler and exit
  285.  * sleep()    unix lookalike
  286.  */
  287.  
  288. /* xioctl - enable xon/xoff protocol */
  289.  
  290. xioctl(flag)
  291. int     flag;
  292. {
  293.     set_xoff(flag);                /* Enable (flag != 0) or
  294.                          * disable flow control */
  295. }
  296.  
  297. /* sigint - restore terminal settings on dialout line */
  298.  
  299. static int sigint()
  300. {
  301.     uninit_comm();
  302.     reset_tty();
  303.     exit(0);
  304. }
  305.  
  306. /* get_time - read time with dos call */
  307.  
  308. static void get_time(n)
  309. TIME_PTR n;
  310. {
  311.     union REGS inregs;
  312.     union REGS outregs;
  313.  
  314.     inregs.h.ah = 0x2c;                /* Please make a #define for
  315.                          * this, Tim */
  316.  
  317.     int86(0x21, &inregs, &outregs);        /* Please #define the 0x21
  318.                          * too */
  319.  
  320.     n->hour = outregs.h.ch;
  321.     n->minute = outregs.h.cl;
  322.     n->sec = outregs.h.dh;
  323.     n->hsec = outregs.h.dl;
  324. }
  325.  
  326. #define    get_sec(n)    (get_time(&n),n.sec)
  327.  
  328. sleep(x)
  329. int     x;
  330. {
  331.     TIME    n;                /* current time record */
  332.     unsigned s = get_sec(n);
  333.  
  334.     while (x-- > 0) {
  335.     while (s == get_sec(n))
  336.          /* void */ ;
  337.     s = n.sec;
  338.     }
  339. }
  340.  
  341. #endif                    /* MSDOS */
  342.